use serde::{Deserialize, Serialize};

#[derive(Clone, Serialize, Deserialize, Debug, Default)]
pub struct TagInfo {
    pub epc: String,
    pub tid: String,
    pub rssi: u8,
    pub state: u8,
    pub detail: String,
    color: String,
}

#[derive(Clone, Serialize, Deserialize, Debug, Default)]
pub struct Filter {
    pub epc: String,
    pub tid: String,
    pub rssi: u8,
    pub enable: bool,
}

impl TagInfo {
    fn new(epc: String, tid: String, rssi: u8, state: u8) -> Self {
        let color = match state {
            0 => "white".to_string(),
            1 => "green".to_string(),
            2 => "yellow".to_string(),
            _ => "red".to_string(),
        };
        TagInfo {
            epc,
            tid,
            rssi,
            state,
            detail: String::new(),
            color,
        }
    }

    pub fn to_info(epc: String, tid: String, rssi: u8, filter: Filter) -> TagInfo {
        let epc_start = epc.starts_with(&filter.epc);
        let tid_start = tid.starts_with(&filter.tid);
        let rssi_comp = rssi > filter.rssi;

        let tag_info = match (filter.enable, epc_start, tid_start, rssi_comp) {
            (false, _, _, _) => TagInfo::new(epc, tid, rssi, 0),
            (true, true, true, true) => TagInfo::new(epc, tid, rssi, 1),
            (true, true, true, false) => TagInfo::new(epc, tid, rssi, 2),
            _ => TagInfo::new(epc, tid, rssi, 3),
        };
        return tag_info;
    }

    pub fn check_consistency(&mut self, index: usize, new_epc: String, new_tid: String) {
        if self.epc == new_epc && self.tid == new_tid {
            self.detail.push_str(&format!("receck[{}]:OK;", index));
        } else {
            self.state = 4;
            let detail = format!("receck[{}]:epc-[{}]tid-[{}];", index, new_epc, new_tid);
            self.detail.push_str(&detail);
        }
    }

}
